﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;

namespace GameJam
{
    public class GameCtrl : MonoBehaviour {

        private CameraCtrl cameraCtrl;
        public Vector3 camera_start_game_anim_pos;
        [System.NonSerialized]
        public bool isCanJoinPlayer = false;
        private List<TreePlayer> player_list = new List<TreePlayer>();
        public GameObject player_prefab;

        [SerializeField]
        List<Color> _colorList;
        int _playerCount = 0;

		[SerializeField]
		SpriteRenderer _treeDark;

        private Transform stage;
        private Transform hero_layer;
        private Transform born_pos;
        private bool isHadStartGameCounter = false;
        private float startGameTimer = 5;
        private bool isHadStartGame = false;
        public bool IsHadStartGame
        {
            get
            {
                return isHadStartGame;
            }
        }



		static GameCtrl _instance;
		public static GameCtrl Instance {get { return _instance;}}
		void Awake()
		{
			_instance = this;
            //Debug.Log(ColorUtility.ToHtmlStringRGBA(_colorList[0]));
        }

        // Use this for initialization
        void Start() {
            stage = GameObject.Find("stage").transform;
            hero_layer = stage.Find("hero");
            born_pos = stage.Find("born_pos");
            cameraCtrl = Camera.main.GetComponent<CameraCtrl>();
            Application.targetFrameRate = 60;
            Debug.logger.logEnabled = false;
            //StartCoroutine(DelayStart());
        }

        IEnumerator DelayStart()
        {
            yield return new WaitForEndOfFrame();
            cameraCtrl.StartGameMove(camera_start_game_anim_pos);
            yield return new WaitForSeconds(5);
            _treeDark.DOFade(1.0f, 2);
            yield return new WaitForSeconds(2);
            ScorePointCtrl.Instance.ShowAllPoint();
            UIMgr.Instance.gameUI.ShowTips();
            isCanJoinPlayer = true;
        }

        public void FirstStartGame()
        {
            StartCoroutine(DelayStart());
        }

        private void Update()
        {
            if(!isHadStartGameCounter && IsAllPlayerReady())
            {
                if (InControl.InputManager.Devices[0].CommandWasPressed)
                {
                    isHadStartGameCounter = true;
                    UIMgr.Instance.gameUI.StartGameCounter();
                    startGameTimer = 3;
                    UIMgr.Instance.gameUI.HideTips();
                    SetAllPlayerCouldControl(false);
                }
            }

            if(isHadStartGameCounter && !IsHadStartGame)
            {
                startGameTimer -= Time.deltaTime;
                if(startGameTimer <= 0)
                {
                    StartGame();
                }
            }
        }

        private void StartGame()
        {
            isHadStartGame = true;
            isHadStartGameCounter = false;
            m_isGameOver = false;
            cameraCtrl.StartPlayerFollow();
            foreach (TreePlayer p in player_list)
            {
                p.StartGame();
            }

			////_treeDark.DOFade (1.0f, 0.5f);
			ScorePointCtrl.Instance.IsStarted = true;
            EnergySpawner.Instance.IsStarted = true;
        }

        public PlayerBornCtrl GetRebornPossition()
        {
            int random = Random.Range(0, born_pos.childCount);
            return born_pos.GetChild(random).GetComponent<PlayerBornCtrl>();
        }

        public void AddPlayer(InControl.InputDevice device)
        {
            GameObject player_obj = Instantiate(player_prefab);

            TreePlayer player = player_obj.GetComponent<TreePlayer>();
            player.attach_device = device;
            player.transform.parent = hero_layer;
            //player.transform.localPosition = born_pos.GetChild(_playerCount * 2).localPosition;
            player.BaseColor = _colorList[_playerCount];
            player.player_index = _playerCount;
            cameraCtrl.player_list.Add(player);
            player_list.Add(player);
            isHadStartGameCounter = false;
            player.Born(born_pos.GetChild(_playerCount).GetComponent<PlayerBornCtrl>());
            ++_playerCount;
            ResetAllPlayerToNoReady();
        }

        public bool IsAllPlayerReady()
        {
            if (player_list.Count == 0) return false;
            bool isAllReady = true;
            foreach(TreePlayer p in player_list)
            {
                if(!p.IsReady)
                {
                    isAllReady = false;
                    break;
                }
            }
            return isAllReady;
        }

        public void ResetAllPlayerToNoReady()
        {
            foreach(TreePlayer p in player_list)
            {
                p.IsReady = false;
            }
            UIMgr.Instance.gameUI.ResetAllPlayerToUnReady();

        }

		public int GetAllPlayerEnergies()
		{
			int sum = 0;
			for (int i = 0; i < player_list.Count; ++i) {
				sum += player_list [i].Energy;
			}
			return sum;
		}

		public int AllPlayerNeedEnergies()
		{
			int sum = 0;
			for (int i = 0; i < player_list.Count; ++i) {
				sum += player_list [i].MaxEnergy;
			}
			return sum;
		}

		public int MaxEnergyInGame()
		{
			return AllPlayerNeedEnergies () - player_list.Count + 1;
		}

		public int AllEnergyInGame()
		{
			return GetAllPlayerEnergies () + EnergySpawner.Instance.CurEnergyOnGround;
		}

		public void SetAllPlayerCouldControl(bool bCouldControl)
		{
			for (int i = 0; i < player_list.Count; ++i) {
				player_list [i].CouldControl = bCouldControl;
			}
		}

        public void ReStartGame()
        {
            for (int i = 0; i < player_list.Count; ++i)
            {
                TreePlayer p = player_list[i];
                p.RestartGame();
                p.transform.localPosition = born_pos.GetChild(p.player_index).localPosition;
            }
            isHadStartGame = false;
            isHadStartGameCounter = false;
            m_isGameOver = false;
            EnergySpawner.Instance.ReStartGame();
            ScorePointCtrl.Instance.RestartGame();
            StartCoroutine(DelayReStart());
            UIMgr.Instance.gameOverUI.Hide();
            //UIMgr.Instance.gameUI.ResetAllPlayerToUnReady();
        }

        IEnumerator DelayReStart()
        {
            yield return new WaitForEndOfFrame();
            cameraCtrl.StartGameMove(camera_start_game_anim_pos);
            yield return new WaitForSeconds(5);
            _treeDark.DOFade(1.0f, 2);
            yield return new WaitForSeconds(2);
            UIMgr.Instance.gameUI.ShowTips();
            ScorePointCtrl.Instance.ShowAllPoint();
            cameraCtrl.StartPlayerFollow();
            //for (int i = 0; i < player_list.Count; ++i)
            //{
            //    TreePlayer p = player_list[i];
            //    p.RestartGame();
            //}
        }

        bool m_isGameOver = false;
        public bool IsGameOver
        {
            get
            {
                return m_isGameOver;
            }
        }
        public void GameOver()
        {
            if (m_isGameOver) return;
            m_isGameOver = true;
            string statics_str = "";
            EnergySpawner.Instance.DespawnAll();
            for (int i = 0; i < player_list.Count; ++i)
            {
                TreePlayer p = player_list[i];
                int percent = (int)((float)p.Score / 11 * 100);
                statics_str += "<color=#" + ColorUtility.ToHtmlStringRGBA(_colorList[i]) + ">" + percent + "%</color>\n";
                p.GameOver();

            }
            statics_str.Replace("\\n","\n");

            _treeDark.DOFade (100.0f / 255.0f, 2f);
            cameraCtrl.GameOverMove(statics_str);
			ScorePointCtrl.Instance.IsStarted = false;
            ScorePointCtrl.Instance.HideAllPoint();
        }
    }
}